package com.yeyks.commonReference.service.consumer.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.yeyks.activity.dal.domain.ActivityNodeUserRecord;
import com.yeyks.activity.service.ActivityNodeUserRecordService;
import com.yeyks.common.constants.RechargeRecordStatus;
import com.yeyks.common.constants.activity.RedisKeyPreConstant;
import com.yeyks.common.dto.UserMemberCardWebDTO;
import com.yeyks.common.em.MemberCardStatus;
import com.yeyks.common.em.RechangeRecordEnum;
import com.yeyks.common.em.UserMemberCardBillType;
import com.yeyks.common.em.pay.PayAttach;
import com.yeyks.common.em.pay.PayTypeEnum;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.common.param.UserMemberCardQueryParam;
import com.yeyks.common.utils.ArgumentsCheckUtil;
import com.yeyks.common.utils.IdWorkerUtil;
import com.yeyks.common.utils.ObjectConvertUtil;
import com.yeyks.common.utils.RedisUtil;
import com.yeyks.commonReference.append.pay.PayService;
import com.yeyks.commonReference.append.redis.RedisService;
import com.yeyks.commonReference.append.sms.SmsService;
import com.yeyks.commonReference.append.statistic.StatisticBaseService;
import com.yeyks.commonReference.pojo.param.activity.HotelJipInvite.ActivityHotelJipInviteActiveCardParam;
import com.yeyks.commonReference.service.config.RechargeConfigService;
import com.yeyks.commonReference.service.consumer.MemberCardService;
import com.yeyks.commonReference.service.consumer.UserMemberCardService;
import com.yeyks.config.dal.domain.RechargeConfig;
import com.yeyks.consumer.dal.dao.UserMemberCardMapper;
import com.yeyks.consumer.dal.domain.*;
import com.yeyks.consumer.dto.UserMemberCardDTO;
import com.yeyks.consumer.param.UserMemberCard.*;
import com.yeyks.consumer.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


/**
 * <p>
 * 用户会员卡表 服务实现类
 * </p>
 *
 * @author yun
 * @since 2019-06-25
 */
@Slf4j
@Service
public class UserMemberCardServiceImpl extends ServiceImpl<UserMemberCardMapper, UserMemberCard> implements UserMemberCardService {

    @Autowired
    private PayService payService;
    @Autowired
    private MemberCardService memberCardService;
    @Autowired
    private UserMemberCardBillService billService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private RechargeRecordService recordService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RechargeConfigService rechargeConfigService;
    @Autowired
    private UserInviteRelationService userInviteRelationService;
    @Autowired
    private StatisticBaseService statisticBaseService;
    @Autowired
    private ActivityNodeUserRecordService activityNodeUserRecordService;

    /**
     * 通过用户id查询该用户的会员卡信息
     *
     * @return
     */
//    @Override
//    public UserMemberCard getByUserId(Integer userId) {
//        return baseMapper.getByUserId(userId);
//    }

    //查询用户信息
    @Override
    public UserMemberCard getUserMemberCard(Integer userid, Integer cardType) {
        UserMemberCard userMemberCard = getOne(new QueryWrapper<UserMemberCard>()
                .eq(UserMemberCard.USER_ID, userid)
                .eq(UserMemberCard.CARD_TYPE, cardType)
                .eq(UserMemberCard.IS_DEL, 0)
                .last("limit 1")
        );
        return userMemberCard;
    }

    /**
     * 通过用户id查询该用户的会员卡信息
     *
     * @return UserMemberCardDTO
     */
    @Override
    public UserMemberCardDTO getDTOByUserId(UserMemberCardInfoParam param) {
        UserMemberCard userMemberCard = getUserMemberCard(param.getUserId(), param.getCardType());
        if (userMemberCard == null) {
            log.info("该用户未绑定会员卡{}", param.getUserId());
            return null;
        }
        return getUserMemberCardDTO(userMemberCard);
    }

    /**
     * 用户设置支付密码
     */
    @Override
    public void setPwd(UserMemberCardSetPwdParam param) {
        if (!smsService.verifySmsForSignup(param.getPhone(), param.getCode())) {
            throw new ServiceException("验证码输入有误");
        }
        if (ArgumentsCheckUtil.strIsNull(param.getPayPassword())) {
            throw new ServiceException("支付密码不能为空");
        }
        UserInfo userInfo = userInfoService.getById(param.getUserId());
        if (!Objects.equals(param.getPhone(), userInfo.getPhone())) {
            throw new ServiceException("非本人手机号，拒绝操作");
        }
        UserMemberCard userMemberCard = getUserMemberCard(param.getUserId(), param.getCardType());
        if (Objects.isNull(userMemberCard)) {
            throw new ServiceException("用户没有该类型会员卡");
        }
        int res = baseMapper.update(null, new UpdateWrapper<UserMemberCard>()
                .set(UserMemberCard.PAY_PASSWORD, param.getPayPassword())
                .set(UserMemberCard.UPDATE_TIME, new Date())
                .eq(UserMemberCard.ID, userMemberCard.getId())
        );
        if (res != 1) {
            throw new ServiceException("设置密码异常");
        }
    }

    /**
     * 用户修改支付密码
     */
    @Override
    public void updatePwd(UserMemberCardUpdatePwdParam param) {
        UserMemberCard userMemberCard = getUserMemberCard(param.getUserId(), param.getCardType());
        if (userMemberCard == null) {
            log.info("该用户未绑卡userId = {}", param.getUserId());
            throw new ServiceException("该用户未绑卡");
        }
        if (!Objects.equals(param.getOldPassword(), userMemberCard.getPayPassword())) {
            throw new ServiceException("原始支付密码有误，请重新输入");
        }
        if (Objects.equals(param.getOldPassword(), param.getNewPassword())) {
            throw new ServiceException("原支付密码不能与新密码相同");
        }
        int res = baseMapper.update(null, new UpdateWrapper<UserMemberCard>()
                .set(UserMemberCard.PAY_PASSWORD, param.getNewPassword())
                .set(UserMemberCard.UPDATE_TIME, new Date())
                .eq(UserMemberCard.ID, userMemberCard.getId())
        );
        if (res != 1) {
            throw new ServiceException("修改密码异常");
        }
    }

    /**
     * 增加会员卡金额
     *
     * @return
     */
    @Override
    @Transactional
    public Boolean addAmount(final UserMemberCardAddAmountParam param) {
        try {
            return redisUtil.runWithLock(RedisKeyPreConstant.USER_MEMBER_CARD_PAY_LOCK + param.getUserId(), () -> {
                //首先查询该用户是否已经绑卡
                UserMemberCard userMemberCard = getUserMemberCard(param.getUserId(), param.getCardType());
                if (userMemberCard == null) {
                    log.info("该用户未绑定会员卡userId = {}", param.getUserId());
                    return false;
                }
                //增加总的付款金额和赠送金额，并增加可用的付款金额和赠送金额
                int nowTotalPayAmount = userMemberCard.getTotalPayAmount() == null ? 0 : userMemberCard.getTotalPayAmount();
                int nowTotalGiveAmount = userMemberCard.getTotalGiveAmount() == null ? 0 : userMemberCard.getTotalGiveAmount();
                int nowRemainPayAmount = userMemberCard.getRemainPayAmount() == null ? 0 : userMemberCard.getRemainPayAmount();
                int nowRemainGiveAmount = userMemberCard.getRemainGiveAmount() == null ? 0 : userMemberCard.getRemainGiveAmount();
                int newPayAmount = param.getPayAmount() == null ? 0 : param.getPayAmount();
                int newGiveAmount = param.getGiveAmount() == null ? 0 : param.getGiveAmount();
                //计算之后的结果
                int afterTotalPayAmount = nowTotalPayAmount + newPayAmount;
                int afterTotalGiveAmount = nowTotalGiveAmount + newGiveAmount;
                int afterRemainPayAmount = nowRemainPayAmount + newPayAmount;
                int afterRemainGiveAmount = nowRemainGiveAmount + newGiveAmount;
                boolean update = update(
                        new UpdateWrapper<UserMemberCard>()
                                .set(UserMemberCard.TOTAL_PAY_AMOUNT, afterTotalPayAmount)
                                .set(UserMemberCard.TOTAL_GIVE_AMOUNT, afterTotalGiveAmount)
                                .set(UserMemberCard.REMAIN_PAY_AMOUNT, afterRemainPayAmount)
                                .set(UserMemberCard.REMAIN_GIVE_AMOUNT, afterRemainGiveAmount)
                                .set(UserMemberCard.UPDATE_TIME, new Date())

                                .eq(UserMemberCard.ID, userMemberCard.getId())
                                .eq(UserMemberCard.TOTAL_PAY_AMOUNT, nowTotalPayAmount)
                                .eq(UserMemberCard.TOTAL_GIVE_AMOUNT, nowTotalGiveAmount)
                                .eq(UserMemberCard.REMAIN_PAY_AMOUNT, nowRemainPayAmount)
                                .eq(UserMemberCard.REMAIN_GIVE_AMOUNT, nowRemainGiveAmount)
                );
                if (update) {
                    UserMemberCardBill bill = new UserMemberCardBill();
                    bill.setUserId(userMemberCard.getUserId());
                    bill.setCardId(userMemberCard.getCardId());
                    bill.setPayAmount(newPayAmount);
                    bill.setGiveAmount(newGiveAmount);
                    bill.setOrderNo(param.getOrderNo());
                    bill.setOperatorAmount(bill.getGiveAmount() + bill.getPayAmount());
                    bill.setRemark(param.getRemark());
                    bill.setType(param.getType());
                    bill.setRemainAmount(afterRemainPayAmount + afterRemainGiveAmount);
                    bill.setCreateTime(new Date());
                    bill.setCardType(param.getCardType());
                    Integer res = billService.insert(bill);
                    return res == 1;
                } else {
                    return false;
                }
            });
        } catch (Exception e) {
            log.error("增加会员卡金额出错{}", e.getLocalizedMessage());
        }
        return false;
    }

    /**
     * 减少会员卡金额
     *
     * @param amount  操作金额
     * @param userId  用户id
     * @param remark  备注
     * @param type    账单类型：0充值，1消费
     * @param orderNo 消费订单号
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void descAmount(Integer amount, Integer userId, Integer type, String remark, String orderNo, Integer cardType) {
        try {
            redisUtil.runWithLock(RedisKeyPreConstant.USER_MEMBER_CARD_PAY_LOCK + userId, () -> {
                //首先查询该用户是否已经绑卡
                UserMemberCard userMemberCard = getUserMemberCard(userId, cardType);
                if (userMemberCard == null) {
                    log.info("该用户未绑定会员卡userId = {}", userId);
                    throw new ServiceException("该用户未绑定会员卡");
                }
                //总的付款金额和赠送金额不变，首先扣除可用付款金额，可用付款金额扣除完毕扣除可用赠送金额，否则提示金额不足
                int nowRemainPayAmount = userMemberCard.getRemainPayAmount() == null ? 0 : userMemberCard.getRemainPayAmount();
                int nowRemainGiveAmount = userMemberCard.getRemainGiveAmount() == null ? 0 : userMemberCard.getRemainGiveAmount();
                int newAmount = amount == null ? 0 : amount;
                if (nowRemainGiveAmount + nowRemainPayAmount < newAmount) {
                    log.info("该会员卡余额不足remain = {}, amount = {}", nowRemainGiveAmount + nowRemainPayAmount, newAmount);
                    throw new ServiceException("会员卡余额不足,请先去充值");
                }
                //如果可用付款金额少于操作金额，则先扣完可用付款金额，再扣除可用赠送金额
                //使用的赠送余额
                int giveAmount = 0;
                //使用的充值余额
                int payAmount = 0;
                //支付后的结果
                int afterRemainPayAmount = 0;
                int afterRemainGiveAmount = 0;
                if (nowRemainPayAmount < newAmount) {
                    //扣除完可用付款金额后，还需付remain
                    giveAmount = newAmount - nowRemainPayAmount;
                    afterRemainPayAmount = 0;
                    afterRemainGiveAmount = nowRemainGiveAmount - giveAmount;
                    payAmount = nowRemainPayAmount;
                } else { //可用付款金额多于操作金额，直接扣除可用付款金额
                    afterRemainPayAmount = nowRemainPayAmount - newAmount;
                    afterRemainGiveAmount = nowRemainGiveAmount;
                    payAmount = newAmount;
                }
                userMemberCard.setUpdateTime(new Date());
                boolean update = update(
                        new UpdateWrapper<UserMemberCard>()
                                .set(UserMemberCard.REMAIN_PAY_AMOUNT, afterRemainPayAmount)
                                .set(UserMemberCard.REMAIN_GIVE_AMOUNT, afterRemainGiveAmount)
                                .set(UserMemberCard.UPDATE_TIME, new Date())

                                .eq(UserMemberCard.ID, userMemberCard.getId())
                                .eq(UserMemberCard.REMAIN_PAY_AMOUNT, nowRemainPayAmount)
                                .eq(UserMemberCard.REMAIN_GIVE_AMOUNT, nowRemainGiveAmount)
                );
                if (update) {
                    UserMemberCardBill bill = new UserMemberCardBill();
                    bill.setUserId(userMemberCard.getUserId());
                    bill.setCardId(userMemberCard.getCardId());
                    bill.setPayAmount(payAmount);
                    bill.setGiveAmount(giveAmount);
                    bill.setOrderNo(orderNo);
                    bill.setOperatorAmount(bill.getGiveAmount() + bill.getPayAmount());
                    bill.setRemark(remark);
                    bill.setType(type);
                    bill.setRemainAmount(afterRemainPayAmount + afterRemainGiveAmount);
                    bill.setCreateTime(new Date());
                    bill.setCardType(cardType);
                    Integer res = billService.insert(bill);
                    return res == 1;
                } else {
                    return false;
                }
            });
        } catch (Exception e) {
            log.error("减少会员卡金额出错{}", e.getLocalizedMessage());
        }
    }

    //jip邀请活动绑卡
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void inviteActivityUserBindCard(ActivityHotelJipInviteActiveCardParam param) {
        redisUtil.runWithLock("vip:memberCard:enableOrderPay:online", () -> {
            //判断用户是否可以绑卡
            //是否是会员
            UserMemberCard userMemberCard = getUserMemberCard(param.getUserId(), 2);
            if (Objects.nonNull(userMemberCard)) {
                throw new ServiceException("您已绑定会员卡");
            }
            //是否已经邀请了10人
            Integer inviteUserCount = userInviteRelationService.getInviteUserCount(CollectionUtil.newArrayList(5), param.getUserId());
            if (inviteUserCount < 10) {
                throw new ServiceException("邀请人数不够");
            }
            //查询可用的卡
            MemberCard memberCard = memberCardService.getOne(
                    new QueryWrapper<MemberCard>()
                            .eq(MemberCard.ENABLE, 0)
                            .eq(MemberCard.STATUS, 1)
                            .in(MemberCard.CARD_TYPE, 2)
                            .in(MemberCard.SALE_TYPE, 2)
                            .last("limit 1")
            );
            //修改卡的可绑定状态
            if (null != memberCard) {
                boolean update = memberCardService.update(
                        new UpdateWrapper<MemberCard>()
                                .eq(MemberCard.ID, memberCard.getId())
                                .set(MemberCard.ENABLE, 1)
                );
                if (!update) {
                    throw new ServiceException("绑定失败,请重试");
                }
            } else {
                throw new ServiceException("现已没有可用的会员卡");
            }
            //绑卡
            UserMemberCardBindCardParam userMemberCardBindCardParam = new UserMemberCardBindCardParam();
            userMemberCardBindCardParam.setUserId(param.getUserId());
            userMemberCardBindCardParam.setCardType(2);
            userMemberCardBindCardParam.setCardNo(memberCard.getCardNo());
            userMemberCardBindCardParam.setPassword(memberCard.getPassword());
            userMemberCardBindCardParam.setPayPassword(param.getPassword());
            userBindCard(userMemberCardBindCardParam);
            //统计绑卡人数
            activityNodeUserRecordService.save(
                    new ActivityNodeUserRecord()
                    .setActivityCode("activity_hotel_jip_invite")
                    .setNode("card")
                    .setUserId(param.getUserId())
            );
            return null;
        });
    }

    /**
     * 用户绑卡
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void userBindCard(UserMemberCardBindCardParam param) {
        try {
            //校验用户的会员卡信息
            MemberCard memberCard = checkCard(param.getCardNo(), param.getPassword(), param.getUserId(), param.getCardType());
            Date date = new Date();
            int year = 1;
            switch (param.getCardType()) {
                case 1:
                    year = 5;
                    break;
                case 2:
                    year = 1;
                    break;
            }
            //更新卡信息
            boolean b = memberCardService.update(
                    new UpdateWrapper<MemberCard>()
                            .set(MemberCard.STATUS, MemberCardStatus.BIND.value())
                            .set(MemberCard.BIND_CARD_DATE, date)
                            .set(MemberCard.EXPIRED_DATE, DateUtil.offset(date, DateField.YEAR, year))
                            .set(MemberCard.UPDATE_TIME, new Date())
                            .eq(MemberCard.ID, memberCard.getId())
            );
            if (!b) {
                throw new ServiceException("绑卡失败");
            }
            //更新用户卡关系信息
            UserInfo userInfo = userInfoService.getById(param.getUserId());
            UserMemberCard userMemberCard = new UserMemberCard();
            userMemberCard.setCardType(param.getCardType());
            userMemberCard.setUserId(userInfo.getId());
            userMemberCard.setCardId(memberCard.getId().intValue());
            userMemberCard.setIsDel(0);
            userMemberCard.setTotalPayAmount(0);
            userMemberCard.setRemainPayAmount(0);
            //初始余额v3.8.3
            Integer remainAmount = memberCard.getRemainAmount();
            if (Objects.isNull(remainAmount) || remainAmount < 0) {
                remainAmount = 0;
            }
            userMemberCard.setTotalGiveAmount(remainAmount);
            userMemberCard.setRemainGiveAmount(remainAmount);
            userMemberCard.setPhone(userInfo.getPhone());
            userMemberCard.setCreateTime(date);
            userMemberCard.setUpdateTime(date);
            if(StrUtil.isNotBlank(param.getPassword())){
                userMemberCard.setPayPassword(param.getPayPassword());
            }
            int res = baseMapper.insert(userMemberCard);
            if (res != 1) {
                log.error("用户绑定异常res = {}", res);
                throw new ServiceException("绑定异常");
            }
            //将用户变为vip
            boolean i = userInfoService.update(new UpdateWrapper<UserInfo>()
                    .set(UserInfo.IS_VIP, 1)
                    .eq(UserInfo.ID, param.getUserId())
            );
            if (!i) {
                log.error("用户成为会员异常res = {}", res);
            }
            //绑创客
            recordService.bindRecharge(userInfo.getPhone(), param.getInviteId());
        } catch (ServiceException e) {
            throw new ServiceException(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("绑卡失败");
        }
    }

    /**
     * 检测用户支付密码是否正确
     *
     * @param userId
     * @param password
     * @return
     */
    @Override
    public Boolean checkPayPassword(Integer userId, Integer cardType, String password) {
        UserMemberCard card = getUserMemberCard(userId, cardType);
        if (card == null) {
            throw new ServiceException("您未绑定会员卡");
        }
        return password.equals(card.getPayPassword());
    }

    /**
     * 使用钱包支付
     *
     * @param userId
     * @param password
     * @param payAmount
     * @param orderNo
     * @return
     */
    @Override
    public Boolean cardPay(Integer userId, String password, Integer payAmount, String orderNo, Integer cardType) {

        if (ArgumentsCheckUtil.strIsNull(password)) {
            throw new ServiceException("请输入支付密码");
        }
        String value = redisService.getValue("payPwd:" + userId);
        if (value != null && Integer.valueOf(value) >= 3) {
            throw new ServiceException("您连续三次输入密码错误，24小时内无法使用臻享钱包支付");
        }
        //验证支付密码是否正确
        Boolean flag = checkPayPassword(userId, cardType, password);
        if (!flag) {
            if (value == null) {
                redisService.setValueTimeOut("payPwd:" + userId, "1", 60 * 60 * 24);
            } else {
                redisService.increValue("payPwd:" + userId);
            }
            int size = 3 - Integer.valueOf(redisService.getValue("payPwd:" + userId));
            if (size <= 0) {
                throw new ServiceException("您连续三次输入密码错误，24小时内无法使用臻享钱包支付");
            } else {
                throw new ServiceException("密码输入有误，还有" + size + "次输入机会");
            }
        }
        redisService.deleteKey("payPwd:" + userId);
        //减少余额
        descAmount(payAmount, userId, UserMemberCardBillType.CONSUME.value(), UserMemberCardBillType.CONSUME.desc(), orderNo, cardType);
        return true;
    }

    /**
     * 校验用户需要绑定的会员卡信息
     *
     * @param cardNo
     * @param password
     */
    @Override
    public MemberCard checkCard(String cardNo, String password, Integer userId, Integer cardType) {
        //首先判断该用户是否已经绑定过会员卡
        UserMemberCard userMemberCard = getUserMemberCard(userId, cardType);
        if (userMemberCard != null) {
            throw new ServiceException("您已绑定过会员卡");
        }
        MemberCard memberCard = memberCardService.getOne(
                new QueryWrapper<MemberCard>()
                        .eq(MemberCard.CARD_NO, cardNo)
                        .eq(MemberCard.CARD_TYPE, cardType)
                        .last("limit 1")
        );
        if (memberCard == null) {
            log.info("通过卡号查询该卡不存在cardNo = {}", cardNo);
            throw new ServiceException("该卡不存在");
        }
        if (Objects.equals(memberCard.getEnable(), 0)) {
            throw new ServiceException("该卡尚未可以激活");
        }
        if (MemberCardStatus.NO_ACTIVATE.value().equals(memberCard.getStatus())) {
            throw new ServiceException("该卡尚未被激活");
        }
        if (MemberCardStatus.BIND.value().equals(memberCard.getStatus())) {
            throw new ServiceException("该卡已被绑定");
        }
        if (!memberCard.getPassword().equalsIgnoreCase(password)) {
            throw new ServiceException("密码输入错误");
        }
        return memberCard;
    }

    //生成充值订单
    @Override
    public Map<String, Object> rechargeOrder(UserMemberCardRechargeOrderParam param) {
        //判断用户是否是会员
        checkUserVip(param.getUserId(), param.getCardType());
        //判断套餐是否存在并可用
        RechargeConfig rechargeConfig = rechargeConfigService.checkPackage(param.getUserId(), param.getCardType(), param.getPayAmount());

        UserMemberCard userMemberCard = getUserMemberCard(param.getUserId(), param.getCardType());
        UserInfo userInfo = userInfoService.getById(userMemberCard.getUserId());
        MemberCard memberCard = memberCardService.getById(userMemberCard.getCardId());

        String orderNo = IdWorkerUtil.nextStrId();
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setOrderNo(orderNo);
        rechargeRecord.setPayAmount(param.getPayAmount());
        RechangeRecordEnum rechangeRecordEnum = null;
        switch (param.getCardType()) {
            case 1:
                rechangeRecordEnum = RechangeRecordEnum.MEMBER_CARD_RECHANGE_VIP;
                break;
            case 2:
                rechangeRecordEnum = RechangeRecordEnum.MEMBER_CARD_RECHANGE_JIP;
                break;
            default:
                throw new ServiceException("会员卡类型错误");
        }
        rechargeRecord.setType(rechangeRecordEnum.value());
        rechargeRecord.setOrderDesc(rechangeRecordEnum.desc());
        rechargeRecord.setUserId(param.getUserId());
        Date date = new Date();
        rechargeRecord.setCreatedTime(date);
        rechargeRecord.setUpdatedTime(date);
        rechargeRecord.setGiveAmount(rechargeConfig.getGiveAmount());
        rechargeRecord.setPhone(userInfo.getPhone());
        rechargeRecord.setCardNo(memberCard.getCardNo());
        recordService.insert(rechargeRecord);
        return ImmutableMap.of("orderId", rechargeRecord.getId());
    }

    /**
     * 会员卡充值
     *
     * @return
     */
    @Override
    public Object rechargePay(UserMemberCardRechargePayParam param) {
        //首先判断该用户是否绑定会员卡
//        UserMemberCard userMemberCard = getUserMemberCard(param.getUserId(),param.getCardType());
//        if (Objects.isNull(userMemberCard)) {
//            throw new ServiceException("该用户未绑卡");
//        }
        checkUserVip(param.getUserId(), param.getCardType());
        RechargeRecord rechargeRecord = recordService.selectById(param.getOrderId());
        if (Objects.isNull(rechargeRecord)) {
            throw new ServiceException("该充值订单不存在");
        }
        setRechargeRecord(param.getType(), rechargeRecord);
        Integer update = recordService.update(rechargeRecord);
        if (update != 1) {
            throw new ServiceException("更新订单支付方式失败");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("orderNo", rechargeRecord.getOrderNo());
        if (payService.doPay(map, PayAttach.CARD_PAY.desc(), param.getType(), rechargeRecord.getOrderNo(), rechargeRecord.getPayAmount(), param.getOpenId(), param.getIp(), null, null)) {
            return map;
        }
        return null;
    }

    private void setRechargeRecord(String type, RechargeRecord rechargeRecord) {
        rechargeRecord.setStatus(RechargeRecordStatus.prePay);
        //支付方式，0微信，1支付宝，4小程序，5公众号
        if (PayTypeEnum.ALIPAY.desc().equals(type)) {
            rechargeRecord.setPaymentMethod(PayTypeEnum.ALIPAY.value());
        }
        if (PayTypeEnum.WXPAY.desc().equals(type)) {
            rechargeRecord.setPaymentMethod(PayTypeEnum.WXPAY.value());
        }
        if (PayTypeEnum.XCX.desc().equals(type)) {
            rechargeRecord.setPaymentMethod(PayTypeEnum.XCX.value());
        }
        if (PayTypeEnum.GZH.desc().equals(type)) {
            rechargeRecord.setPaymentMethod(PayTypeEnum.GZH.value());
        }
        rechargeRecord.setUpdatedTime(new Date());
    }

    private UserMemberCardDTO getUserMemberCardDTO(UserMemberCard userMemberCard) {

        try {
            UserMemberCardDTO userMemberCardDTO = ObjectConvertUtil.convertObject(userMemberCard, UserMemberCardDTO.class);
            Integer remainPayAmount = userMemberCard.getRemainPayAmount();
            Integer remainGiveAmount = userMemberCard.getRemainGiveAmount();
            int totalRemainAmount = (remainGiveAmount == null ? 0 : remainGiveAmount) + (remainPayAmount == null ? 0 : remainPayAmount);
            userMemberCardDTO.setTotalRemainAmount(totalRemainAmount);
            MemberCard memberCard = memberCardService.selectById(userMemberCard.getCardId());
            if (memberCard != null) {
                userMemberCardDTO.setHotelId(memberCard.getHotelId());
                userMemberCardDTO.setCardNo(memberCard.getCardNo());
            }
            UserInfo userInfo = userInfoService.getById(userMemberCard.getUserId());
            userMemberCardDTO.setAvatar(userInfo.getAvatar());
            userMemberCardDTO.setPhone(userInfo.getPhone());
            userMemberCardDTO.setUserType(userInfo.getType());
            return userMemberCardDTO;
        } catch (Exception e) {
            log.error("用户会员卡对象转换失败{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return null;
    }

    //判断用户是否是会员
    @Override
    public Boolean checkUserVip(Integer userId, Integer cardType) {
        UserMemberCard userMemberCard = getUserMemberCard(userId, cardType);
        if (null == userMemberCard) {
            throw new ServiceException(403001,"非会员用户");
        } else {
            MemberCard memberCard = memberCardService.getById(userMemberCard.getCardId());
            if (Objects.isNull(memberCard)) {
                throw new ServiceException("会员卡不存在");
            } else if (DateUtil.compare(memberCard.getExpiredDate(), new Date()) < 0) {
                throw new ServiceException("会员卡已过期");
            }
            return true;
        }
    }

    @Override
    public List<UserMemberCardWebDTO> queryByParam(UserMemberCardQueryParam param) {

        List<UserMemberCardWebDTO> dtoList = Lists.newArrayList();
        QueryWrapper<UserMemberCard> wrapper = new QueryWrapper<UserMemberCard>();
        if (!StringUtils.isEmpty(param.getPhone())) {
            wrapper.like(UserMemberCard.PHONE, param.getPhone());
        }
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<UserMemberCard> cards = this.baseMapper.selectList(wrapper);
        if (!CollectionUtils.isEmpty(cards)) {
            dtoList = ObjectConvertUtil.convertList(cards, UserMemberCardWebDTO.class);
        }
        return dtoList;
    }

    @Override
    public int queryCount(UserMemberCardQueryParam param) {
        QueryWrapper<UserMemberCard> wrapper = new QueryWrapper<UserMemberCard>();
        if (!StringUtils.isEmpty(param.getPhone())) {
            wrapper.like(UserMemberCard.PHONE, param.getPhone());
        }
        return this.baseMapper.selectCount(wrapper);
    }

    /**
     * 通过会员卡id和卡类型查询该用户卡信息
     *
     * @param cardId
     * @return
     */
    @Override
    public UserMemberCard selectByCardId(Long cardId, Integer cardType) {
        UserMemberCard userMemberCard = baseMapper.selectOne(new QueryWrapper<UserMemberCard>()
                .eq(UserMemberCard.CARD_ID, cardId)
                .eq(UserMemberCard.CARD_TYPE, 2)
                .last("limit 1")
        );
        return userMemberCard;
    }

    //检查卡密码是否可以设置
    @Override
    public boolean checkPwd(Integer userId, Integer cardType) {
        boolean result = false;
        UserMemberCard userMemberCard = getUserMemberCard(userId, cardType);
        if (Objects.isNull(userMemberCard)){
            throw new ServiceException("卡不存在");
        }else {
            if (Objects.isNull(userMemberCard.getPayPassword())){
                result = true;
            }else {
                result = false;
            }
        }
        return result;
    }

}
